import { ExtractionTask } from './types';
import { GitService, GitConfig } from './services/GitService';
import { FileScanner } from './core/FileScanner';
import { JavaParser } from './parsers/JavaParser';
import { logger } from './utils/logger';
import { env } from './utils/env';
import path from 'path';
import fs from 'fs';
import { EventEmitter } from 'events';
import { TranslationPackLoader } from './services/TranslationPackLoader';

export class TranslationExtractor extends EventEmitter {
  private gitService: GitService;
  private fileScanner: FileScanner;
  private javaParser: JavaParser;
  private translationPackLoader: TranslationPackLoader;
  private isRunning: boolean = false;
  private task: ExtractionTask;

  constructor(task: ExtractionTask) {
    super(); // 初始化 EventEmitter
    
    if (!task.gitConfig) {
      throw new Error('Git 配置不能为空');
    }

    this.task = task;

    // 初始化 Git 服务
    const gitConfig: Partial<GitConfig> = {
      repository: task.gitConfig.repository,
      branch: task.gitConfig.branch,
      username: task.gitConfig.username || '',
      token: task.gitConfig.token || '',
      clonePath: task.gitConfig.clonePath || path.join(env.storage.repositoryPath, path.basename(task.gitConfig.repository, '.git')),
      updateStrategy: task.gitConfig.updateStrategy || 'clone',
      sshKey: task.gitConfig.sshKey
    };
    this.gitService = new GitService(gitConfig);

    // 初始化文件扫描器
    this.fileScanner = new FileScanner(task);

    // 初始化 Java 解析器
    this.javaParser = new JavaParser();
    
    // 初始化语言包加载器
    this.translationPackLoader = new TranslationPackLoader();
    
    // 监听JavaParser的解析完成事件
    this.javaParser.on('parseCompleted', (result) => {
      // 转发事件到TranslationExtractor
      this.emit('parseCompleted', result);
    });

    // 注册事件监听器
    this.fileScanner.on('scanCompleted', async (result) => {
      logger.info('扫描完成', { 
        总文件数: result.files.length,
        // 文件列表: result.files.map(f => path.basename(f)) 
      });
      
      // 加载语言包配置
      await this.loadLanguageConfigurations();
      
      // 处理扫描到的文件
      const results: any[] = [];
      const matchedFiles: string[] = [];
      const unmatchedFiles: string[] = [];
      
      try {
        // 确保即使没有匹配的文件也能创建结果
        let hasMatchedFiles = false;
        
        for (const file of result.files) {
          // 根据 parserConfig 中的 keyPatterns 匹配文件
          const keyPatterns = task.parserConfig?.[0]?.options?.keyPatterns || ['**/*.java', '**/*.kt'];
          const isMatchingFile = keyPatterns.some((pattern: string) => {
            const regex = new RegExp(pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*'));
            return regex.test(file);
          });
          
          if (isMatchingFile) {
            hasMatchedFiles = true;
            matchedFiles.push(path.basename(file));
            try {
              const extractionResult = await this.javaParser.parseFile(file, task);
              results.push(extractionResult);
              
            } catch (error) {
              const errorTime = new Date().getTime();
              logger.error('文件解析失败', { 
                文件路径: file,
                错误信息: error instanceof Error ? error.message : String(error)
              });
              // 添加错误结果
              results.push({
                taskId: task.taskId,
                status: 'failed' as const,
                startTime: new Date().toISOString(),
                endTime: new Date().toISOString(),
                statistics: {
                  totalFiles: 1,
                  processedFiles: 0,
                  extractedKeys: 0,
                  errors: 1,
                  processingTime: 0
                },
                translations: [],
                analysis: {
                  coverage: {
                    overall: 0,
                    byLanguage: {},
                    byModule: {},
                    missingKeys: [],
                    redundantKeys: []
                  },
                  usage: {
                    highFrequency: [],
                    lowFrequency: [],
                    unusedKeys: []
                  },
                  modules: {},
                  quality: {
                    duplicates: [],
                    namingIssues: [],
                    contextIssues: []
                  }
                },
                errors: [{
                  file,
                  message: error instanceof Error ? error.message : String(error)
                }],
                suggestions: []
              });
            }
          } else {
            unmatchedFiles.push(path.basename(file));
          }
        }

        // 确保在所有文件处理完成后保存结果
        // 即使没有匹配的文件也创建一个结果文件
        if (!hasMatchedFiles && results.length === 0) {
          logger.warn('没有匹配的文件需要解析，创建空结果');
          results.push({
            taskId: task.taskId,
            status: 'success' as const,
            startTime: new Date().toISOString(),
            endTime: new Date().toISOString(),
            statistics: {
              totalFiles: result.files.length,
              processedFiles: 0,
              extractedKeys: 0,
              errors: 0,
              processingTime: 0
            },
            translations: [],
            analysis: {
              coverage: {
                overall: 0,
                byLanguage: {},
                byModule: {},
                missingKeys: [],
                redundantKeys: []
              },
              usage: {
                highFrequency: [],
                lowFrequency: [],
                unusedKeys: []
              },
              modules: {},
              quality: {
                duplicates: [],
                namingIssues: [],
                contextIssues: []
              }
            },
            errors: [],
            suggestions: []
          });
        }
        
        // 保存解析结果
        const reportsDir = path.join(process.cwd(), 'reports');
        if (!fs.existsSync(reportsDir)) {
          logger.info(`创建报告目录: ${reportsDir}`);
          fs.mkdirSync(reportsDir, { recursive: true });
        }

        const exportPath = path.join(
          task.reportConfig?.exportPath || reportsDir, 
          `source-result-${Date.now()}.json`
        );
        
        // 保存结果，并将解析完成的结果传递给回调
        await this.javaParser.saveResults(results, exportPath, (mergedResult) => {
          // 触发解析完成事件，并传递合并后的结果
          this.emit('parseCompleted', {
            result: mergedResult,
            exportPath: exportPath
          });
        });
        
        logger.info('解析完成', {
          总文件数: results.length,
          成功文件数: results.filter(r => r.status === 'success').length,
          失败文件数: results.filter(r => r.status === 'failed').length,
          // 匹配的文件: matchedFiles,
          未匹配的文件: unmatchedFiles,
          导出路径: exportPath
        });
      } catch (error) {
        logger.error('处理扫描文件过程中发生错误', {
          错误信息: error instanceof Error ? error.message : String(error)
        });
        
        // 即使出错也创建结果文件
        try {
          const reportsDir = path.join(process.cwd(), 'reports');
          if (!fs.existsSync(reportsDir)) {
            fs.mkdirSync(reportsDir, { recursive: true });
          }
          
          const errorResult = {
            taskId: task.taskId,
            status: 'failed' as const,
            startTime: new Date().toISOString(),
            endTime: new Date().toISOString(),
            statistics: {
              totalFiles: result.files.length,
              processedFiles: 0,
              extractedKeys: 0,
              errors: 1,
              processingTime: 0
            },
            translations: [],
            analysis: {
              coverage: { overall: 0, byLanguage: {}, byModule: {}, missingKeys: [], redundantKeys: [] },
              usage: { highFrequency: [], lowFrequency: [], unusedKeys: [] },
              modules: {},
              quality: { duplicates: [], namingIssues: [], contextIssues: [] }
            },
            errors: [{
              message: error instanceof Error ? error.message : String(error)
            }],
            suggestions: []
          };
          
          const errorPath = path.join(reportsDir, `extraction-result-error-${Date.now()}.json`);
          fs.writeFileSync(errorPath, JSON.stringify(errorResult, null, 2), 'utf-8');
          logger.info(`已保存错误结果文件: ${errorPath}`);
          
          // 触发解析错误事件
          this.emit('parseError', {
            error: error,
            errorResult: errorResult,
            errorPath: errorPath
          });
        } catch (saveError) {
          logger.error('保存错误结果失败', {
            错误信息: saveError instanceof Error ? saveError.message : String(saveError)
          });
          
          // 触发严重错误事件
          this.emit('criticalError', saveError);
        }
      }
    });

    this.fileScanner.on('scanError', (error) => {
      logger.error('扫描错误', { error: error instanceof Error ? error.message : String(error) });
      // 转发扫描错误事件
      this.emit('scanError', error);
    });
  }

  /**
   * 加载语言包配置
   * 首先尝试从 API 加载，如果失败则从本地文件加载
   */
  private async loadLanguageConfigurations(): Promise<void> {
    try {
      logger.info('开始加载语言包配置');
      
      // 1. 尝试从任务配置中获取 API URL
      const apiUrl = this.task.translationConfig?.android?.apiUrl || this.task.translationConfig?.ios?.apiUrl;
      let loaded = false;
      
      // 2. 如果配置了 API URL，尝试从 API 加载
      if (apiUrl) {
        logger.info('尝试从 API 加载可用的语言包列表', { apiUrl });
        loaded = await this.translationPackLoader.loadFromApi(
          apiUrl, 
          this.task.languages || ['en', 'zh-CN']
        );
      }
      
      // 3. 如果 API 加载失败或未配置 API，尝试从本地文件加载
      if (!loaded) {
        logger.info('从本地文件加载语言包');
        loaded = await this.translationPackLoader.loadFromLocalFiles(this.task);
      }
      
      // 4. 如果成功加载语言包，将加载器注入到 JavaParser
      if (loaded) {
        logger.info('语言包加载成功，注入到解析器');
        this.javaParser.setTranslationLoader(this.translationPackLoader);
      } else {
        logger.warn('语言包加载失败，将使用原始键名作为翻译值');
      }
    } catch (error) {
      logger.error('加载语言包配置出错', { 
        error: error instanceof Error ? error.message : String(error) 
      });
    }
  }

  public async start(): Promise<void> {
    if (this.isRunning) {
      logger.warn('翻译提取服务已在运行中');
      return;
    }

    try {
      this.isRunning = true;
      logger.info('正在启动翻译提取服务...');

      // 克隆或更新仓库
      await this.gitService.cloneOrUpdate();
      
      // 加载已定义的翻译键
      if (this.task.translationConfig) {
        const resourceDirs: string[] = [];
        
        // 收集 Android 资源目录
        if (this.task.translationConfig.android?.resourcePaths) {
          resourceDirs.push(...this.task.translationConfig.android.resourcePaths.map(p => 
            path.join(this.gitService.getRepoPath(), p.sourcePath)));
        }
        
        // 收集 iOS 资源目录
        if (this.task.translationConfig.ios?.resourcePaths) {
          resourceDirs.push(...this.task.translationConfig.ios.resourcePaths.map(p => 
            path.join(this.gitService.getRepoPath(), p.sourcePath)));
        }
        
        // 收集 Web 资源目录
        if (this.task.translationConfig.web?.resourcePaths) {
          resourceDirs.push(...this.task.translationConfig.web.resourcePaths.map(p => 
            path.join(this.gitService.getRepoPath(), p.sourcePath)));
        }
        
        // 加载已定义的翻译键
        if (resourceDirs.length > 0) {
          logger.info('加载已定义的翻译键', { 资源目录: resourceDirs });
          await this.javaParser.loadDefinedTranslationKeys(resourceDirs);
        }
      }

      // 开始扫描文件
      const files = await this.fileScanner.scan();
      logger.info('文件扫描完成', { totalFiles: files.length });

      logger.info('翻译提取服务启动成功');
    } catch (error) {
      this.isRunning = false;
      logger.error('翻译提取服务启动失败', { error: error instanceof Error ? error.message : String(error) });
      throw error;
    }
  }

  public async stop(): Promise<void> {
    if (!this.isRunning) {
      logger.warn('翻译提取服务未在运行');
      return;
    }

    try {
      this.isRunning = false;
      logger.info('正在停止翻译提取服务...');

      // 清理 Git 仓库
      await this.gitService.cleanup();

      logger.info('翻译提取服务停止成功');
    } catch (error) {
      logger.error('翻译提取服务停止失败', { error: error instanceof Error ? error.message : String(error) });
      throw error;
    }
  }
} 